package com.zzyl.service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.Constants;
import com.zzyl.dto.WxLoginDto;
import com.zzyl.entity.Member;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.mapper.NursingProjectMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.service.CustomerService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import com.zzyl.vo.NursingProjectVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class CustomerServiceImpl implements CustomerService {

    @Value("${zzyl.framework.wx.appid}")
    private String appid;

    @Value("${zzyl.framework.wx.secret}")
    private String secret;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    /**
     * 第三方：微信的登录认证
     * @param wxLoginDto
     * @return
     */
    @Override
    public LoginVo login(WxLoginDto wxLoginDto) {
        //1.通过登录凭证完成登录 获取到唯一的openid
        String openId = getOpenId(wxLoginDto.getCode());
        //2.通过openid查询数据库的表
        Member member = memberMapper.selectByOpenId(openId);
        //3.通过手机兑换码获取手机号
        String phone = getPhone(wxLoginDto.getPhoneCode());
        //4.判断用户是否为新用户 如果是则注册 如果不是则更新用户的手机号
        if (null == member){
            //新用户 --> 新增
            member = new Member();
            member.setPhone(phone);
            member.setCreateTime(LocalDateTime.now());
            member.setUpdateTime(LocalDateTime.now());
            member.setCreateBy(1L);
            member.setOpenId(openId);
            String name = Constants.DEFAULT_NICKNAME_PREFIX.
                    get((int)(Constants.DEFAULT_NICKNAME_PREFIX.size()*Math.random())) + phone.substring(7);
            member.setName(name);

            memberMapper.save(member);
        }else {
            if (!phone.equals(member.getPhone())){
                member.setPhone(phone);
                member.setUpdateTime(LocalDateTime.now());

                memberMapper.update(member);
            }
        }
        //5.生成token
        Map<String,Object> claims=new HashMap<>();
        claims.put("id",member.id);
        claims.put("name",member.getName());

        String token = JwtUtil.createJWT
                (jwtTokenManagerProperties.getBase64EncodedSecretKey(),
                        jwtTokenManagerProperties.getTtl(), claims);
        //6.构建返还的结果
        LoginVo vo = new LoginVo();
        vo.setToken(token);
        vo.setNickName(member.getName());

        //
        return vo;
    }

    /**
     * 获取手机号
     * @param phoneCode
     * @return
     */
    public String getPhone(String phoneCode){
        //1.
        String accessToken = getAccessToken();

        //2.
        Map<String,Object> paramData=new HashMap<>();
        paramData.put("code",phoneCode);

        HttpResponse response = HttpUtil.createPost
                (Constants.WX_GET_PHONE_URL + accessToken).body(JSONUtil.toJsonStr(paramData)).execute();
        String body = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(body);
        if (jsonObject.getInt("errcode") != null && jsonObject.getInt("errcode") != 0){
            throw new BaseException(BasicEnum.GET_PHONE_ERROR);
        }
        JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");

        return phoneInfo.getStr("phoneNumber");
    }

    /**
     * 获取token
     * @return
     */
    private String getAccessToken() {
        Map<String,Object> paramData=new HashMap<>();
        paramData.put("appid",appid);
        paramData.put("secret",secret);
        paramData.put("grant_type","client_credential");

        HttpResponse response = HttpUtil.createGet
                (Constants.WX_ACCESS_TOKEN_URL).form(paramData).execute();

        String body = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(body);
        if (jsonObject.getStr("access_token") == null){
            throw new BaseException(BasicEnum.GET_TOKEN_ERROR);
        }
        return jsonObject.getStr("access_token");
    }

    /**
     * 获取openId
     * @param code
     * @return
     */
    private String getOpenId(String code) {
        Map<String,Object> paramData=new HashMap<>();
        paramData.put("appid",appid);
        paramData.put("secret",secret);
        paramData.put("js_code",code);
        paramData.put("grant_type","authorization_code");

        HttpResponse response = HttpUtil.createGet
                (Constants.WX_OPENID_URL).form(paramData).execute();
        String body = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(body);
        if (jsonObject.getInt("errcode") != null){
            //失败了
            throw new BaseException(BasicEnum.GET_OPENID_ERROR);
        }
        return jsonObject.getStr("openid");
    }

}
